#include "gic.h"

void gic_init(void)
{
    GICD_CTLR = 0;
    GICC_CTLR = 0;
    GICC_PMR = 0xFF;
    for (uint32_t i = 0; i < 32; i++) {
        GICD_IPRIORITY(i) = 0xA0A0A0A0; 
    }
    for (uint32_t i = 0; i < 32; i++) {
        GICD_ICENABLER(i) = 0xFFFFFFFF;
    }
    
    for (uint32_t i = 0; i < 32; i++) {
        GICD_ICPENDR(i) = 0xFFFFFFFF;
    }
    GICD_CTLR = 1;
    GICC_CTLR = 1;
}

void gic_enable_irq(uint32_t irq)
{
    uint32_t reg_num = irq / 32;
    uint32_t bit_num = irq % 32;
    
    GICD_ISENABLER(reg_num) = (1 << bit_num);
}

void gic_disable_irq(uint32_t irq)
{
    uint32_t reg_num = irq / 32;
    uint32_t bit_num = irq % 32;
    
    GICD_ICENABLER(reg_num) = (1 << bit_num);
}

void gic_set_priority(uint32_t irq, uint8_t priority)
{
    uint32_t reg_num = irq / 4;
    uint32_t byte_offset = (irq % 4) * 8;
    
    uint32_t reg = GICD_IPRIORITY(reg_num);
    reg &= ~(0xFF << byte_offset);
    reg |= (priority << byte_offset); 
    GICD_IPRIORITY(reg_num) = reg;
}

uint32_t gic_acknowledge_irq(void)
{
    return GICC_IAR;
}

void gic_end_of_irq(uint32_t irq)
{
    GICC_EOIR = irq;
}

